<?php

namespace app;

use app\common\exception\NotFoundException;
use app\common\exception\ParameterFailedException;
use app\common\exception\RuntimeException;
use think\exception\Handle;
use think\exception\HttpException;
use think\facade\Log;
use think\Response;
use Throwable;

/**
 * 应用异常处理类
 */
class ExceptionHandle extends Handle
{
    public $http_code = 500;
    public $error_code = -1;
    public $msg = '系统繁忙，请稍后再试！';
    public $data;

    /**
     * 不需要记录信息（日志）的异常类列表
     * @var array
     */
    protected $ignoreReport = [
        //HttpException::class,
        //HttpResponseException::class,
        //ModelNotFoundException::class,
        //DataNotFoundException::class,
        //ValidateException::class,
    ];

    /**
     * 记录异常信息（包括日志或者其它方式记录）
     *
     * @access public
     * @param  Throwable  $exception
     * @return void
     */
    public function report(Throwable $exception): void
    {
        // 使用内置的方式记录异常日志
        //if (!$exception instanceof \RuntimeException) {
        parent::report($exception);
        //}
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @access public
     * @param  \think\Request  $request
     * @param  Throwable  $e
     * @return Response
     */
    public function render($request, Throwable $e): Response
    {
        switch ($e) {
            case $e instanceof HttpException:
                //请求异常
                $this->http_code  = $e->getStatusCode();
                $this->error_code = -1;
                if (env('APP_DEBUG', '')) {
                    return parent::render($request, $e);
                }
                $this->msg = 'action is not found!';
                break;
            #用户造成的异常 - 数据不存在
            case $e instanceof NotFoundException:
                #用户造成的异常 - 参数异常
            case $e instanceof ParameterFailedException:
                #用户造成的异常 - 基类
            case $e instanceof RuntimeException:
                $this->http_code  = $e->http_code;
                $this->error_code = $e->error_code;
                $this->msg        = $e->msg;
                $this->data       = $e->data;
                break;
            #用户造成的异常 - SPL类
            case $e instanceof \RuntimeException:
                $this->http_code  = 400;
                $this->msg        = $e->getMessage();
                $this->error_code = $e->getCode();
                $this->data       = $e->data;
                break;
            #系统造成的异常
            case $e instanceof \LogicException:
            case $e instanceof \Exception:
                //系统异常 如1/0，记录日志
                //$params = implode(",", \request()->param());
                //new Email("1422476675@qq.com", 'lee', [
                //    "subject" => "系统错误",
                //    "body" => "参数：{$params};详细：{$e->getMessage()}"
                //]);
                $this->msg = '网络繁忙，请稍后再试';
                if (env('APP_DEBUG', '')) {
                    return parent::render($request, $e);
                }
                if (isset($e->data)) {
                    $this->data = $e->data;
                }
                $this->error_code = $e->getCode();
                $this->http_code  = 500;
                Log::error($e->getMessage());
                break;
            default:
                // 其他错误交给系统处理
                return parent::render($request, $e);
                break;
        }

        $result = [
            'code' => $this->error_code,
            'msg'  => $this->msg,
            'data' => $this->data,
        ];

        return json($result, $this->http_code);
    }
}
